home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / documents / audio / audio.apps / dev / sync < prev   
Encoding:
Text File  |  1996-11-11  |  6.8 KB  |  154 lines

  1. OK, I found a number of short explanations on the Net regarding this, but I 
  2. wanted to construct a longer one.
  3.  
  4. IRIX 5.3 introduces new facilities for synchronization of audio and other media.
  5.  
  6. In the Audio Library, the two new functions which correspond to these features
  7. are:
  8.     ALgetframetime
  9.     ALgetframenumber
  10.  
  11. You can find simplistic example code synchronizing audio & MIDI in the 4Dgifts
  12. directory of your SGI:
  13.     ~4Dgifts/examples/midi/syncrecord
  14. This requires Archer Sully's little Midi File Library, which is also included
  15. in 4Dgifts.
  16.  
  17. Synchronizing audio & other media really means synchronizing the media
  18. at the jacks on the back of the machine. This implies that we need 
  19. some method of determining exactly when media data came in an input jack
  20. and scheduling exactly when it will reach an output jack. 
  21.  
  22. First, some definitions.
  23.  
  24. Unadjusted System Time ("UST")
  25. ----------------------------
  26.  
  27. This is a shared timeline between all the media. It called "unadjusted"
  28. because it is never adjusted by "timed" or other agents. UST is a high
  29. resolution clock returned as a 64-bit number in nanoseconds. The
  30. resolution of the actual clock used for UST will vary, but it is always
  31. less than 1 microsecond.
  32.  
  33. Sample Frame Counters
  34. ---------------------
  35. We need a way to reference a particular sample frame in an input
  36. or output stream. So we define a "sample frame counter" at each
  37. input or output device. This just counts all the sample frames that
  38. go by, starting with 0, and incrementing until the system is rebooted.
  39. I should emphasize that the sample frame counter is defined at the
  40. *device*, not the *port* level. In other words, if my system's been
  41. up for a while, and I start a new application which opens an audio port,
  42. the first sample frame number coming into the port will in general NOT
  43. be 0. It's likely to be a very large number, since I'm picking up the 
  44. audio from the input device in mid-stream.
  45.  
  46. Because sample frame numbers are referenced to the device, two different
  47. input applications running simultaneously will have a shared timeline. If
  48. each gets a sample numbered "10000," it will be the same sample in each
  49. application. Sample-frame numbering is sample-accurate.
  50.  
  51. Similarly,because sample frame numbers are referenced to the device,
  52. two different output applications running simultaneously will have a
  53. shared timeline (because they share the same device). If each
  54. application puts out a sample at frame "10000," the two samples will
  55. arrive at the output device simultaneously and be mixed together. I've
  56. actually written an application which puts out two sine-waves 180
  57. degrees out of phase from another application, and the output of the
  58. two applications will exactly cancel.
  59.  
  60. ALgetframenumber will return the sample-frame number, relative to the
  61. device, of the next frame to be read or written from a port. Note that
  62. while a port is not overflowing or underflowing, this number stays
  63. constant. This is because the port is a queue; on an input port, the
  64. sample frame number of the queue head stays constant while samples pile
  65. up behind it. On an output port, the sample frame number of the queue
  66. tail stays constant while samples drain out the other end to the audio
  67. device. However, if you're underflowing or overflowing, this number 
  68. will be changing (and you can't synchronize until you get out of underflow
  69. or overflow).
  70.  
  71. If I want to output audio at a particular sample frame, I can just 
  72. write 0's to the port until I get to that sample frame. Similarly, if I
  73. want to read a particular sample frame from input, I can drop the input
  74. until I get there.
  75.  
  76. Time Synchronization
  77. --------------------
  78. Here's how we describe how to start & stop things at the same time, and
  79. how to make precise temporal calculations relative to audio.
  80.  
  81. OK, so now we know how to determine which sample-frame number we're reading
  82. or writing. How can we relate the sample-frame numbers to the time at which
  83. a sample frame came in or will go out?
  84.  
  85. The ALgetframetime call returns an atomic pair of (UST, sample frame). The
  86. pair is very carefully defined: the UST is the time at which the given sample
  87. frame came into the machine or will go out of the machine. The software will
  88. compensate for all the group delays through the A/D or D/A converters, if
  89. necessary. 
  90.  
  91. Note that you do not have any control over which pair is returned by
  92. ALgetframetime. It is merely guaranteed to return a "recent" pair. So you
  93. have to do a tiny bit of algebra to figure out what you want.
  94.  
  95. Here's an example.
  96.  
  97. I want to know at what time (UST) the next sample I write will go out the jack.
  98. I call ALgetframetime() to get some (UST, sample frame) pair. Suppose it 
  99. returns (t, 10000). So I know that sample frame 10000 hit the output jack at
  100. time t. Now I call ALgetframenumber() to determine what the sample frame number
  101. is for the next sample frame to be written. It tells me 11000 (because in
  102. general the sample I'm writing into the port is newer than the sample going
  103. out the jack).
  104.  
  105. So I can now determine the time at which sample frame 11000 goes out. It's just
  106.     t + (11000-10000)*(#nanoseconds/sample)
  107. The number of nanoseconds per sample can be precomputed from the sample rate.
  108.  
  109. Note that the equation is exactly the same for an input port -- if you use
  110. signed values for the sample-frame numbers.
  111.  
  112. Here's a little more complicated example.
  113.  
  114. Suppose I want my audio to start at the same time as a particular video frame.
  115.  
  116. I determine the UST t at which that video frame is to go out (not hard given
  117. the frame rate and a UST/frame-number pair from video). 
  118.  
  119. Then I calculate the audio sample frame N which corresponds to that UST
  120. (t): I call ALgetframetime and do the algebra using the pair I get back
  121. and my knowledge of the sample rate.
  122.  
  123. Now I determine the next sample frame N0 in my port, using ALgetframenumber.
  124. If N0 is not < N, I've already missed the video frame. If N0 < N, I write
  125. (N-N0) sample frames of 0's into the port, followed by my audio.
  126.  
  127. For MIDI, I can determine the UST of an input message, and schedule an output
  128. message using UST, so the concepts are similar.
  129.  
  130. Rate Synchronization
  131. --------------------
  132.  
  133. We still have the problem of drift: once I start things in sync, the rates of 
  134. the different media streams will be slightly different, so the media will
  135. drift.
  136.  
  137. A common way to solve this is to actually lock the clock of the audio
  138. device to that of the video device (or other audio device). You can run
  139. the A/D, AES transmitter, and D/A off of the recovered clock from the
  140. AES digital input (use the "digital" rate). 
  141.  
  142. To slave one audio device to another, you just run the AES output of
  143. the master into the AES input of the slave, and run the slave off of 
  144. the recovered clock from its AES input.
  145.  
  146. You can generate an AES clock from a video stream using an external
  147. box such as the TimeLine MicroLynx (TimeLine Vista, Inc: (619) 727-3300).
  148.  
  149. Summary
  150. -------
  151.  
  152. Hopefully this will get you started. I have some code examples which I'll
  153. include here soon.
  154.